/*
******************************************************************************************************* 
**  Copyright (C) 2022, 苏州检易生物科技有限公司 
**  All rights reserved. 
** 
**  FileName:			gpio.c
**  Description:	
**  Author:       ZengDa 	 
**  Version				v0.1
**  Date:					2022-05-11
**	Function List： 
**  History:         
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                              	调试开关
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/
#include "drive_dc.h"
#include "can_mem.h"
#include "can_task.h"
/*
*********************************************************************************************************
*                                              	宏定义
*********************************************************************************************************
*/

 
/*
*********************************************************************************************************
*                                              	函数原型声明
*********************************************************************************************************
*/

#if VALVE_DRIVE_CAN_BUS
static uint8_t drive_dc_func(void* arg);
#endif
static valve_cfg_t m_valve_cfg[VALVE_NUM] =
{
	{.enable = 1,.node_id = 0x11,.chn = 1},
	{.enable = 1,.node_id = 0x11,.chn = 2},
	{.enable = 1,.node_id = 0x11,.chn = 3},
	{.enable = 1,.node_id = 0x11,.chn = 4},
	{.enable = 1,.node_id = 0x11,.chn = 5},
	{.enable = 1,.node_id = 0x11,.chn = 6},
	{.enable = 1,.node_id = 0x11,.chn = 7},
	{.enable = 1,.node_id = 0x11,.chn = 8},
	{.enable = 1,.node_id = 0x11,.chn = 9},
	{.enable = 1,.node_id = 0x11,.chn = 10},
	{.enable = 1,.node_id = 0x11,.chn = 11},
	{.enable = 1,.node_id = 0x11,.chn = 12},
	{.enable = 1,.node_id = 0x11,.chn = 13},
	{.enable = 1,.node_id = 0x11,.chn = 14},
	{.enable = 1,.node_id = 0x11,.chn = 15},
	{.enable = 1,.node_id = 0x11,.chn = 16},
	{.enable = 1,.node_id = 0x11,.chn = 17},
	{.enable = 1,.node_id = 0x11,.chn = 18},
	{.enable = 1,.node_id = 0x11,.chn = 19},
	{.enable = 1,.node_id = 0x11,.chn = 20},
	{.enable = 1,.node_id = 0x11,.chn = 21},
	{.enable = 1,.node_id = 0x11,.chn = 22},
	{.enable = 1,.node_id = 0x11,.chn = 23},
	{.enable = 1,.node_id = 0x11,.chn = 24},
};
/*
*********************************************************************************************************
*                                              	变量定义
*********************************************************************************************************
*/
#if VALVE_DRIVE_CAN_BUS
static drive_dc_t drive_dc_array[VALVE_NUM] = {0};
static volatile uint32_t dc_value = 0;
#endif
/*
*********************************************************************************************************
*                                              	函数定义
*********************************************************************************************************
*/

void drive_dc_init(void)
{
#if VALVE_DRIVE_CAN_BUS
	for(uint8_t i = 0;i<VALVE_NUM;i++)
	{
		drive_dc_array[i].p_cfg = &m_valve_cfg[i];
		if(drive_dc_array[i].p_cfg->chn >= CAN_DRIVE_DC_MAX)
		{
			Critical_Log("DRIVE DC index %d channel out range!\r\n",i);
		}
	}
#else
//	valve_init();
#endif
}
void drive_dc_act(drive_dc_index_t index,drive_dc_act_t act,schedule_cb_t* p_tcb)
{
#if VALVE_DRIVE_CAN_BUS
	ASSERT(p_tcb);
	if(index >= VALVE_NUM || 0 == drive_dc_array[index].p_cfg->enable )
		return;
	act_t * p_act = list_new(&p_tcb->send_list);
	if(p_act == NULL)
	{
		Critical_Log("Act node create failed!\r\n");
		return;
	}
	p_act->func = drive_dc_func;
	p_act->p_tcb = p_tcb;
	drive_dc_arg_t* p_arg =(drive_dc_arg_t*) &p_act->arg;
	p_arg->index = index;
	p_arg->dc_act = act;
	list_push(&p_tcb->send_list,p_act);
	return;
#else
	valve_act(index,act,p_tcb);
#endif
}
#if VALVE_DRIVE_CAN_BUS
static uint8_t drive_dc_func(void* arg)
{
	ASSERT(arg);
	act_t* p_act = (act_t*)arg;
	uint8_t rlt = ACT_RLT_DEL;
	rt_base_t it = rt_hw_interrupt_disable();
	drive_dc_arg_t* p_arg =(drive_dc_arg_t*)&p_act->arg;
	drive_dc_t* p_dc = &drive_dc_array[p_arg->index];
	
	can_mem_node_t* p_msg;
	
	if(p_arg->dc_act == DRIVE_DC_OPEN_MUTEX)
	{
		if(p_dc->on_cnt != 0)
		{
			rlt = ACT_RLT_NONE;
		}
		else
		{
			p_dc->on_cnt++;
			p_msg = can_mem_malloc();
			dc_value = (1 << (p_dc->p_cfg->chn - 1)) | dc_value;
			dc_write(p_dc->p_cfg,M_REG_DC,dc_value,&p_msg->can_msg);
			app_msg_send(CAN_MSG_PUSH,(uint32_t)p_msg,&g_can_task.mailbox);
			Trace_Log("DC open index %d,on cnt %d;\r\n",p_arg->index,p_dc->on_cnt);
		}
	}
	else if(p_arg->dc_act == DRIVE_DC_OPEN)
	{
		if(p_dc->on_cnt != 0)
		{
			p_dc->on_cnt++;
		}
		else
		{
			p_dc->on_cnt++;
			p_msg = can_mem_malloc();
			dc_value = (1 << (p_dc->p_cfg->chn - 1)) | dc_value;
			dc_write(p_dc->p_cfg,M_REG_DC,dc_value,&p_msg->can_msg);
			app_msg_send(CAN_MSG_PUSH,(uint32_t)p_msg,&g_can_task.mailbox);
		}
		Trace_Log("DC open index %d,on cnt %d;\r\n",p_arg->index,p_dc->on_cnt);
	}
	else if(p_arg->dc_act == DRIVE_DC_CLOSE)
	{
		if(p_dc->on_cnt != 0)
		{
			p_dc->on_cnt--;
		}
		if(p_dc->on_cnt == 0)
		{
			p_msg = can_mem_malloc();
			dc_value = (~(1 << (p_dc->p_cfg->chn - 1))) & dc_value;
			dc_write(p_dc->p_cfg,M_REG_DC,dc_value,&p_msg->can_msg);
			app_msg_send(CAN_MSG_PUSH,(uint32_t)p_msg,&g_can_task.mailbox);
		}
		Trace_Log("DC close index %d,on cnt %d;\r\n",p_arg->index,p_dc->on_cnt);
	}
	else if(p_arg->dc_act == DRIVE_DC_OPEN_NCNT)
	{
		p_dc->on_cnt = 1;
//		if(p_dc->on_cnt == 1)
		{
			p_msg = can_mem_malloc();
			dc_value = (1 << (p_dc->p_cfg->chn - 1)) | dc_value;
			dc_write(p_dc->p_cfg,M_REG_DC,dc_value,&p_msg->can_msg);
			app_msg_send(CAN_MSG_PUSH,(uint32_t)p_msg,&g_can_task.mailbox);
			Trace_Log("DC open index %d,on cnt %d;\r\n",p_arg->index,p_dc->on_cnt);
		}
		Trace_Log("DC open index %d,on cnt %d;\r\n",p_arg->index,p_dc->on_cnt);
	}
	else if(p_arg->dc_act == DRIVE_DC_CLOSE_NCNT)
	{
		p_dc->on_cnt = 0;
//		if(p_dc->on_cnt == 0)
		{
			p_msg = can_mem_malloc();
			dc_value = (~(1 << (p_dc->p_cfg->chn - 1))) & dc_value;
			dc_write(p_dc->p_cfg,M_REG_DC,dc_value,&p_msg->can_msg);
			app_msg_send(CAN_MSG_PUSH,(uint32_t)p_msg,&g_can_task.mailbox);
		}
		Trace_Log("DC close index %d,on cnt %d;\r\n",p_arg->index,p_dc->on_cnt);
	}
	rt_hw_interrupt_enable(it);
	return rlt;
}
#endif